#!/usr/bin/env python

# copyright 2010 Studio Cypher, LLC
# developer: Will Emigh
# projects@studiocypher.com

# Custom modules
from authentication import user_required
from authentication import get_account_from_user
from models import Level
from models import Account

# Built-in or Google modules
import cgi
import os
from google.appengine.ext.webapp import template
from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app
from google.appengine.api import users
from google.appengine.ext.webapp.util import login_required

# Return the template values for the given account
def get_template_values(account, view_account):
    if account.key() == view_account.key():
        pronoun = "you"
    else:
        pronoun = "they"
    xp_msg = pronoun.capitalize()+' need '+str(account.xp_to_next())+' more XP to reach the next level.'
    if view_account.xp_to_next() <= 0:
        xp_msg = pronoun.capitalize()+' have enough XP to level up!'
        
    # Create the string telling them what goods they need
    goods_msg = 'To level up, '+pronoun+' need '
    necessary_goods = Level.goods(view_account.level + 1)
    if necessary_goods[0] > 0:
        goods_msg += str(necessary_goods[0])+' each of '
        goods_msg += str(necessary_goods[1])+' types of common goods'
    if necessary_goods[2] > 0:
        goods_msg += ' and '
        goods_msg += str(necessary_goods[2])+' each of '
        goods_msg += str(necessary_goods[3])+' types of specialty goods'
    goods_msg += '.'
    
    template_values = {
        'xp_msg': xp_msg,
        'account': account,
        'goods_msg': goods_msg,
        'reqs': necessary_goods,
        'view_account': view_account,
        }
    
    return template_values

class NewPage(webapp.RequestHandler):

    # Show the TOS or, if they've accepted, create a new account
    @login_required
    def get(self):
        user = users.get_current_user()
        # If they already have an account, redirect to main
        account = get_account_from_user(user)
        if (account):
            self.redirect("/")
            return
    
        path = os.path.join(os.path.dirname(__file__), 'tos.html')
        self.response.out.write(template.render(path, {}))

    # Called from the TOS form
    # Can't use login_required because it's post
    def post(self):
        user = users.get_current_user()
        # If they already have an account, redirect to main
        account = get_account_from_user(user)
        if (account):
            self.redirect("/")
            return
    
        # If they didn't accept the TOS, show it again
        # If they haven't logged in, show them the TOS again
        if (self.request.get("tos") != 'accept' or user == None):
            path = os.path.join(os.path.dirname(__file__), 'tos.html')
            self.response.out.write(template.render(path, {}))
            return
        
        # Create an account for them
        # This will also create their starting planet, etc.
        Account.create(user, user.email())
        
        self.redirect("/")
        
class ViewPage(webapp.RequestHandler):
        
    # Show this player's level information (and allow them to upgrade)
    @user_required
    def get(self):
        user = users.get_current_user()
        account = get_account_from_user(user)
        
        # By default, they look at their own account
        if self.request.get("id"):
            view_account = Account.get(self.request.get("id"))
        else:
            view_account = account
        
        template_values = get_template_values(account, view_account)
    
        path = os.path.join(os.path.dirname(__file__), 'accounts.html')
        self.response.out.write(template.render(path, template_values))
        
    # Called from the level up screen when they want to use their
    #  goods to level up
    # Can't use account_required because it's a post
    def post(self):
        user = users.get_current_user()
        # If they don't already have an account, redirect to main
        account = get_account_from_user(user)
        if (account == None):
            self.redirect("/")
            return
        
        error_msg = []
        
        # Make sure they have enough XP to level up
        if account.xp_to_next() != 0:
            error_msg.append("You don't have enough XP to level up.")
            
        # Make sure they're sacrificing enough goods to level up
        reqs = Level.goods(account.level + 1)
        goods = self.request.get_all("goods")
                
        # If they didn't set aside enough goods...
        if (len(goods) < reqs[1]):
            msg = "You have to sacrifice "+str(reqs[1])+" types of goods "
            msg += "to level up."
            error_msg.append(msg)
        # If they set aside too many goods...
        if (len(goods) > reqs[1]):
            msg = "You have set aside too many types of goods to sacrifice."
            error_msg.append(msg)
        
        # If there aren't any other errors, make sure they
        #  actually have the resources
        if len(error_msg) == 0:
            for good in goods:
                if (account.good_amount_for(good) < reqs[0]):
                    msg = "You don't have enough "+good+" to sacrifice."
                    error_msg.append(msg)
        
        # Update the goods, increment their level, and display the level info
        if len(error_msg) == 0:
            for good in goods:
                account.update_good(good, -reqs[0])
            msg = account.level_up()
            error_msg.append(msg)
        
        # Display any messages
        template_values = get_template_values(account, account)
        template_values['error_msg'] = error_msg
    
        path = os.path.join(os.path.dirname(__file__), 'accounts.html')
        self.response.out.write(template.render(path, template_values))
        
class Rename(webapp.RequestHandler):

    # Allow them to rename themselves
    def post(self):
        user = users.get_current_user()
        # If they don't already have an account, redirect to main
        account = get_account_from_user(user)
        if (account == None):
            self.redirect("/")
            return
            
        error_msg = []
        
        name = self.request.get("name")
        if name == None or len(name) < 3:
            error_msg.append("Your new name has to have at least 3 characters.")
            # Display any messages
            template_values = get_template_values(account, account)
            template_values['error_msg'] = error_msg
        
            path = os.path.join(os.path.dirname(__file__), 'accounts.html')
            self.response.out.write(template.render(path, template_values))
            return

        account.nickname = name
        account.put()
        
        self.redirect('/accounts/view?id='+str(account.key()))
        
class Logout(webapp.RequestHandler):

    # Redirect to the Google logout
    def get(self):
        self.redirect(users.create_logout_url('/'))
        
class Login(webapp.RequestHandler):

    # Redirect to the Google login
    def get(self):
        self.redirect(users.create_login_url('/'))
                    
application = webapp.WSGIApplication(
                                     [('/accounts/new', NewPage),
                                      ('/accounts/view', ViewPage),
                                      ('/accounts/rename', Rename),
                                      ('/accounts/logout', Logout),
                                      ('/accounts/login', Login)],
                                     debug=True)									 
def main():
    run_wsgi_app(application)

if __name__ == "__main__":
    main()
